package client;

import both.*;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import java.net.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.xml.bind.*;

public class RegistrationTab extends JPanel implements ActionListener, DocumentListener {

    private String fileFolder;
    //still needs uniqueID
    private JButton register;
    private JTextField serverLoc, clientLoc, nameField, teamField;
    private GameShowClient client;
    private int screenWidth = (int) Game.width;
    private int screenHeight = (int) Game.height;
    private static String SERVER = "1";
    private static String CLIENT = "2";
    private static String REGISTER = "3";
    private static int textWidth = 300;

    public RegistrationTab(GameShowClient client) {
        this.client = client;
        add(getServerOutputPanel());
        add(getClientOutputPanel());
        add(getNamePanel());
        add(getTeamPanel());
        add(getRegisterPanel());
        URL url = getClass().getClassLoader().getResource("files.xml");
        String urlString = url.getPath();
        int index = urlString.indexOf("build/classes/files.xml");
        try {
            fileFolder = urlString.substring(0, index) + "src/resources/files.xml";
        } catch (Exception e) {
        }
        try {
            setOutputFolders();
        } catch (JAXBException e) {
            xmlWindow(e);
        }
        setSize(screenWidth / 16, screenHeight / 9);
        setLayout(new GridLayout(0, 1, 10, 30));
        setAlignmentX(JPanel.LEFT_ALIGNMENT);
        setBorder(BorderFactory.createEmptyBorder(30, 30, 30, 30));
    }

    private void setOutputFolders() throws JAXBException {
        JAXBContext jaxbContext = JAXBContext.newInstance(DefaultFiles.class);
        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        File XMLfile = new File(fileFolder);
        DefaultFiles files = (DefaultFiles) jaxbUnmarshaller.unmarshal(XMLfile);
        if (serverLoc == null) {
            serverLoc = new JTextField();
        }
        serverLoc.setText(files.getServerOutput());
        if (clientLoc == null) {
            clientLoc = new JTextField();
        }
        clientLoc.setText(files.getClientOutput());
        client.setServerOutputFolder(serverLoc.getText());
        client.setClientOutputFolder(clientLoc.getText());
    }

    private void xmlWindow(Exception e) {
        JFrame stackFrame = new JFrame("XML Error");
        stackFrame.setBounds(300, 200, 700, 330);
        StackTraceElement[] stackTrace = e.getStackTrace();
        String traceText = e.toString();
        for (StackTraceElement s : stackTrace) {
            traceText = traceText + "\n" + s.toString();
        }
        JTextArea textArea = new JTextArea(traceText);
        textArea.setEditable(false);
        textArea.setSelectedTextColor(Color.RED);
        JScrollPane scrollPane = new JScrollPane(textArea);
        scrollPane.setPreferredSize(new Dimension(700, 330));
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
        JPanel contentPane = new JPanel();
        contentPane.add(scrollPane);
        stackFrame.setContentPane(contentPane);
        stackFrame.pack();
        stackFrame.setVisible(true);
    }

    private JPanel getServerOutputPanel() {
        JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        panel.add(new JLabel(StringFormatter.formatString("Server Output Folder: ", StringFormatter.TITLE_STR, textWidth)));
        serverLoc = new JTextField(25);
        serverLoc.setBackground(Color.WHITE);
        serverLoc.setEnabled(true);
        panel.add(serverLoc);
        JButton browse = new JButton(StringFormatter.formatString("Browse...", StringFormatter.ANSWER_STR, textWidth / 5)); //will be changed
        browse.setActionCommand(SERVER);
        browse.addActionListener(this);
        panel.add(browse);
        return panel;

    }

    private JPanel getClientOutputPanel() {

        JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        panel.add(new JLabel(StringFormatter.formatString("Client Output Folder:  ", StringFormatter.TITLE_STR, textWidth)));
        clientLoc = new JTextField(25);
        clientLoc.setBackground(Color.WHITE);
        clientLoc.setEnabled(true);
        panel.add(clientLoc);
        JButton browse = new JButton(StringFormatter.formatString("Browse...", StringFormatter.ANSWER_STR, textWidth / 5)); //will be changed
        browse.setActionCommand(CLIENT);
        browse.addActionListener(this);
        panel.add(browse);

        return panel;

    }

    private JPanel getNamePanel() {

        JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        panel.add(new JLabel(StringFormatter.formatString("Enter Name: ", StringFormatter.TITLE_STR, 2 * textWidth / 3)));
        nameField = new JTextField(20);
        nameField.getDocument().addDocumentListener(this);
        panel.add(nameField);

        return panel;

    }

    private JPanel getTeamPanel() {

        JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        panel.add(new JLabel(StringFormatter.formatString("Enter Team: ", StringFormatter.TITLE_STR, 2 * textWidth / 3)));
        teamField = new JTextField(20);
        teamField.getDocument().addDocumentListener(this);
        panel.add(teamField);
        return panel;

    }

    private JPanel getRegisterPanel() {

        JPanel panel = new JPanel();
        register = new JButton(StringFormatter.formatString("REGISTER", StringFormatter.TITLE_STR));
        register.setEnabled(false);
        register.setActionCommand(REGISTER);
        register.addActionListener(this);
        panel.add(register);
        return panel;

    }

    public void createXml() throws JAXBException {
        DefaultFiles files = new DefaultFiles();
        JAXBContext jaxbContext = JAXBContext.newInstance(DefaultFiles.class);
        Marshaller jaxbMarshall = jaxbContext.createMarshaller();
        File tgfile = new File(fileFolder);
        jaxbMarshall.marshal(files, tgfile);
    }

    @Override
    public void actionPerformed(ActionEvent event) {

        String eventName = event.getActionCommand();
        if (eventName.equals(SERVER)) {
            JFileChooser chooser = new JFileChooser();
            chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            int returnVal = chooser.showOpenDialog(getParent());
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                serverLoc.setText(chooser.getSelectedFile().toString());
            }
//            try {
//                createXml();
//            } catch (JAXBException ex) {
//                xmlWindow(ex);
//            }
        }


        if (eventName.equals(CLIENT)) {
            JFileChooser chooser = new JFileChooser();
            chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            int returnVal = chooser.showOpenDialog(getParent());
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                clientLoc.setText(chooser.getSelectedFile().toString());
            }
//            try {
//                createXml();
//            } catch (JAXBException ex) {
//                xmlWindow(ex);
//            }
        }


        checkComplete();


        if (eventName.equals(REGISTER)) {
            String name = nameField.getText();
            String team = teamField.getText();


            // The team name will now be converted to have uppercase letters for the first letter
            // The rest of the team name will be turned into lowercase

            String firstTeamNameLetter;
            String restTeamName;

            firstTeamNameLetter = team.substring(0, 1);
            restTeamName = team.substring(1, team.length());
            firstTeamNameLetter = firstTeamNameLetter.toUpperCase();
            restTeamName = restTeamName.toLowerCase();

            team = firstTeamNameLetter.concat(restTeamName);
            teamField.setText(team);


            Contestant contestant = new Contestant();
            contestant.setName(name);
            contestant.setTeamName(team);
            //still need to set uniqueID and send information to server


            //this part below sends the stuff

            client.setServerOutputFolder(serverLoc.getText());
            client.setClientOutputFolder(clientLoc.getText());

            try {
                client.sendRegistration(contestant);
            } catch (UnknownHostException | SocketException e) {
                JOptionPane.showMessageDialog(null,
                        StringFormatter.formatString("Cannot create unique ID", StringFormatter.ANSWER_STR),
                        StringFormatter.formatString("Registration error", StringFormatter.ANSWER_STR),
                        JOptionPane.ERROR_MESSAGE);
            } catch (JAXBException e) {
                JOptionPane.showMessageDialog(null,
                        StringFormatter.formatString("Cannot write registration", StringFormatter.ANSWER_STR),
                        StringFormatter.formatString("Registration error", StringFormatter.ANSWER_STR),
                        JOptionPane.ERROR_MESSAGE);
                e.printStackTrace();
            }
        }
    }

    @Override
    public void changedUpdate(DocumentEvent e) {
        checkComplete();
    }

    @Override
    public void insertUpdate(DocumentEvent e) {
        checkComplete();
    }

    @Override
    public void removeUpdate(DocumentEvent e) {
        checkComplete();
    }

    private void checkComplete() {
        boolean server = !serverLoc.getText().equals("");
        boolean client = !clientLoc.getText().equals("");
        boolean name = !nameField.getText().equals("");
        boolean team = !teamField.getText().equals("");

        if (server && client && name && team) {
            register.setEnabled(true);
        } else {
            register.setEnabled(false);
        }
    }
}
